﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Bunbyx.game
{
    public class Sprite
    {
        // --------------------------------------------------------------------
        //  Constants
        // --------------------------------------------------------------------

        private const string BUNBYX_TEXTURE = "Sprites/Sprites3";
        private const string GOAL_TEXTURE = "Sprites/clock";
        private const string CARROT_TEXTURE = "Sprites/carrot";
        private const string SALAD_TEXTURE = "Sprites/salad";
        private const string IDOL_GOLD_TEXTURE = "Sprites/idol_gold";
        private const string IDOL_SILVER_TEXTURE = "Sprites/idol_silver";
        private const string CLOCK_TEXTURE = "Sprites/clock";

        private const int GOAL_RADIUS = 100;
        private const int CARROT_RADIUS = 50;
        private const int SALAD_RADIUS = 50;
        private const int IDOL_RADIUS = 50;

        // --------------------------------------------------------------------
        //  Enumeration
        // --------------------------------------------------------------------

        public enum SpriteType
        {
            Bunbyx,
            Goal,
            Carrot,
            Salad,
            IdolGold,
            Idol_Silver,
            Clock,
            Other
        }

        // --------------------------------------------------------------------
        //  Public attributes
        // --------------------------------------------------------------------

        public SpriteType Type
        {
            get;
            private set;
        }

        public int Radius
        {
            get;
            private set;
        }

        // The size of the Sprite
        public Rectangle Size
        {
            get;
            private set;
        }

        // The current position of the Sprite
        public Vector2 Position;

        public Vector2 Center
        {
            get
            {
                return Position + new Vector2(Size.Width, Size.Height);
            }
        }

        // The texture object used when drawing the sprite
        public Texture2D SpriteTexture;

        public Rectangle Source
        {
            get { return mSource; }
            set
            {
                mSource = value;
                Size = new Rectangle(0, 0, (int)(mSource.Width * Scale), (int)(mSource.Height * Scale));
            }
        }

        // When the scale is modified throught he property, the Size of the 
        // sprite is recalculated with the new scale applied.
        public float Scale
        {
            get { return mScale; }
            set
            {
                mScale = value;
                //Recalculate the Size of the Sprite with the new scale
                Size = new Rectangle(0, 0, (int)(Source.Width * mScale), (int)(Source.Height * mScale));
            }
        }

        public bool IsDrawable;

        // --------------------------------------------------------------------
        //  Private attributes
        // --------------------------------------------------------------------

        // The asset name for the Sprite's Texture
        private string assetName;

        // Used to size the Sprite up or down from the original image
        private float mScale = 1.0f;

        // The Rectangular area from the original image that  defines the Sprite. 
        private Rectangle mSource;

        // --------------------------------------------------------------------
        //  Constructor
        // --------------------------------------------------------------------

        public Sprite(SpriteType type)
        {
            this.Type = type;
            this.IsDrawable = true;
            this.Position = Vector2.Zero;

            switch (type)
            {
                case SpriteType.Bunbyx:
                    this.assetName = BUNBYX_TEXTURE;
                    break;

                case SpriteType.Goal:
                    this.assetName = GOAL_TEXTURE;
                    this.Radius = GOAL_RADIUS;
                    break;

                case SpriteType.Carrot:
                    this.assetName = CARROT_TEXTURE;
                    this.Radius = CARROT_RADIUS;
                    break;

                case SpriteType.Salad:
                    this.assetName = SALAD_TEXTURE;
                    this.Radius = SALAD_RADIUS;
                    this.Scale = 0.8f;
                    break;

                case SpriteType.IdolGold:
                    this.assetName = IDOL_GOLD_TEXTURE;
                    this.Radius = IDOL_RADIUS;
                    break;

                case SpriteType.Idol_Silver:
                    this.assetName = IDOL_SILVER_TEXTURE;
                    this.Radius = IDOL_RADIUS;
                    break;

                case SpriteType.Clock:
                    this.assetName = CLOCK_TEXTURE;
                    this.Radius = 0;
                    break;

                default:
                    // TODO: Handle error
                    break;
            }
        }

        public Sprite(SpriteType type, Vector2 position)
            : this(type)
        {
            this.Position = new Vector2(position.X, position.Y);
        }

        public Sprite(string assetName)
        {
            this.Type = SpriteType.Other;
            this.assetName = assetName;
            this.IsDrawable = true;
            this.Position = Vector2.Zero;
        }

        public Sprite(string assetName, Vector2 position)
            : this(assetName)
        {
            this.Position = position;
        }

        // --------------------------------------------------------------------
        //  Public methods
        // --------------------------------------------------------------------

        // Load the texture for the sprite using the Content Pipeline
        public virtual void LoadContent(ContentManager contentManager)
        {
            SpriteTexture = contentManager.Load<Texture2D>(assetName);
            Source = new Rectangle(0, 0, SpriteTexture.Width, SpriteTexture.Height);
            if (this.Type == SpriteType.Bunbyx)
            {
                this.Source = new Rectangle(0, 0, 0, 0);
            }
            // Recompute scale again
            Scale = mScale;
        }

        public virtual void Update(GameTime gameTime)
        {
            // Do nothing
        }

        // Draw the sprite to the screen
        public virtual void Draw(SpriteBatch theSpriteBatch)
        {
            if (IsDrawable)
            {
                theSpriteBatch.Draw(SpriteTexture, Position, Source,
                    Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
            }
        }

        public void Move(int dx, int dy)
        {
            Position.X += dx;
            Position.Y += dy;
        }
    }
}
